#pragma once


#include "Type.h"
#include "DecoratedType.h"

class CFunctionTypeGeneralized;

//type of CFuntion* , different function assign to different type
class WHENGINE_API CFunctionType : public CType
{
public:
    CFunctionType();

    static CFunctionType* GetStaticType();
    
    static CFunctionTypeGeneralized *FindFunctionType(const SDecoratedType & ReturnType, const TVector< SDecoratedType > &ParamTypes);

    static CString CreateTypeName(const CString& ReturnType, const TVector<CString>& ParamTypes);
    
    static STypeID CreateID(const SDecoratedType & ReturnType, const TVector< SDecoratedType > &ParamTypes);
    static STypeID CreateID(
        const STypeID & ReturnType
        , const TVector< STypeID > &ParamTypes
        );

};

//type of CFuntion* , different function assign to different type
class WHENGINE_API CFunctionTypeGeneralized : public CType
{
public:


    CFunctionTypeGeneralized(
        const SDecoratedType& ReturnType
        ,const TVector<SDecoratedType>& ParamTypes);

    SDecoratedType GetReturnType()  {return ReturnType;}
    TVector<SDecoratedType> GetParameterTypes()  {return ParamTypes;}
    
    SDecoratedType GetParameterType(uint64_t Index)  {return ParamTypes[Index];}

    //static CFunctionTypeGeneralized* FindFunctionType(CType* ReturnType, const TVector<CType*>& ParamTypes);
    //static CString CreateTypeName(const SDecoratedType & ReturnType, const TVector<SDecoratedType>& ParamTypes);
protected:


    SDecoratedType ReturnType;
    TVector<SDecoratedType> ParamTypes;
    
    void SetTypeArguments( const SDecoratedType & ReturnType,const TVector<SDecoratedType>& InParameterTypes);

    static TMap<TVector<CType*>, CFunctionTypeGeneralized*>& GetFunctionTypeMap();

    static bool CanFunctionUseInScript(const SDecoratedType & ReturnType,const TVector<SDecoratedType>&  ParamTypes) ;

   
};